<template>
  <div v-if="props.expanding">
    <el-checkbox-group
      v-if="props.multiple"
      v-model="selectedValue"
      :disabled="disabled"
      @change="handleChange"
    >
      <el-checkbox
        v-for="(item, index) in state.options"
        :key="index"
        :label="item.dictText"
        :value="item.dictValue"
      />
    </el-checkbox-group>
    <el-radio-group
      v-else
      v-model="selectedValue"
      :disabled="disabled"
      @change="handleChange"
    >
      <el-radio
        v-for="(item, index) in state.options"
        :key="index"
        :label="item.dictText"
        :value="item.dictValue"
      />
    </el-radio-group>
  </div>
  <el-select
    v-else
    v-model="selectedValue"
    :disabled="disabled"
    :multiple="multiple"
    clearable
    :placeholder="placeholder"
    :style="state.style"
    @change="handleChange"
  >
    <el-option
      v-for="(item, index) in state.options"
      :key="index"
      :label="item.dictText"
      :value="item.dictValue"
    />
  </el-select>
</template>
<script setup name="EasyDictSelect" lang="ts">
import { api } from "@/api/common/index";
import { isArray, isBlank } from "@/utils/validate";
import { useMessage } from "@/hooks/message";

const props = defineProps({
  // 文字提示
  placeholder: {
    type: String,
    default: function () {
      return "请选择";
    }
  },
  // 字典项
  dictCode: {
    type: String,
    default: function () {
      return "100";
    }
  },
  width: {
    type: Number,
    default: function () {
      return 160;
    }
  },
  expanding: {
    type: Boolean,
    default: false
  },
  // 是否自动加载数据
  autoQuery: {
    type: Boolean,
    default: function () {
      return true;
    }
  },
  disabled: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  // 是否显示全部选项
  showAll: {
    type: String,
    default: function () {
      return "Y";
    }
  },
  exclude: {
    type: String,
    default: function () {
      return "";
    }
  },
  multiple: {
    type: Boolean,
    default: function () {
      return false;
    }
  },
  // 字典查询地址，一般不需要设置
  queryUrl: {
    type: String,
    default: function () {
      return "/admin/dictentry/get/list";
    }
  }
});

const defaultValue = defineModel<string>("defaultValue");

const emits = defineEmits(["change"]);

const selectedValue = ref(null);

watch(
  () => defaultValue.value,
  val => {
    selectedValue.value = transferValue(val);
  }
);

const transferValue = newValue => {
  if (props.multiple) {
    if (isBlank(newValue)) {
      return [];
    } else if (isArray(newValue)) {
      return newValue;
    } else {
      return newValue.split(",");
    }
  } else {
    if (isBlank(newValue)) {
      return "";
    }
    if (isArray(newValue)) {
      return newValue.join(",");
    } else {
      return newValue;
    }
  }
};

const state = reactive({
  options: [{ dictText: "", dictValue: "" }],
  style: { width: `${props.width}px` }
});

onMounted(async () => {
  if (props.autoQuery) {
    await initQuery();
  }
});

const initQuery = async () => {
  const queryParams = {
    dictCode: props.dictCode,
    showall: props.showAll,
    exclude: props.exclude
  };
  api(props.queryUrl, queryParams)
    .then(res => {
      state.options = res.data;
      setValue(defaultValue.value);
    })
    .catch(err => useMessage().error("获取字典失败"));
};

const setValue = val => {
  selectedValue.value = transferValue(val);
};

const getValue = () => {
  return selectedValue;
};

const handleChange = val => {
  if (props.multiple) {
    if (val && val.length > 0) {
      selectedValue.value = transferValue(val);
      defaultValue.value = val.join(",");
      const options = state.options.filter(item => {
        return item.dictValue === val;
      });
      if (options) {
        emits("change", val.join(","), options);
      } else {
        emits("change", val.join(","));
      }
    }
  } else {
    if (!isBlank(val)) {
      selectedValue.value = transferValue(val);
      defaultValue.value = val;
      const options = state.options.filter(item => {
        return item.dictValue === val;
      });
      if (options) {
        emits("change", val, options[0]);
      } else {
        emits("change", val);
      }
    }
  }
};

// 重新加载数据，供父页面调用
const reload = () => {
  initQuery();
};

defineExpose({
  reload,
  setValue,
  getValue
});
</script>

<style lang="scss" scoped>
.el-input__inner {
  width: 100px;
}
</style>
